﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace jQuery.WebControls
{
    /// <summary>
    /// Text box control which only allows to input numeric data types
    /// </summary>
    [DefaultProperty("Text")]
    [Description("Text box with a mask which only allows to input numeric data types")]
    [ToolboxData("<{0}:NumberTextBox runat=server></{0}:NumberTextBox>")]
    public class NumberTextBox : TextBox
    {
        internal static string suffixCss = "nftb";
        internal static string allowNegatives = "allowneg";
        private jQueryScriptManager jQueryMngr;
        private HorizontalAlign hoAl = HorizontalAlign.Right;
        private string numberValue = String.Empty;

        
        private jQueryScriptManager jQueryManager
        {
            get
            {
                if (jQueryMngr == null)
                    jQueryMngr = Common.Instance.Get_jQueryScriptManager(Page);
                return jQueryMngr;
            }
        }

        #region PROPERTIES
        /// <summary>
        /// Numeric type to apply the correct mask
        /// </summary>
        [Category("Appearance")]
        [DefaultValue("NumericFormat.Integer")]
        [Localizable(true)]
        [Description("Numeric type to apply the correct mask")]
        public NumericFormat NumericType
        {
            get
            {
                if (ViewState["nt"] == null)
                {
                    ViewState.Add("nt", NumericFormat.Integer);
                }
                return (NumericFormat)Enum.Parse(typeof(NumericFormat), ViewState["nt"].ToString());
            }
            set
            {                
                ViewState["nt"] = value;
            }
        }
        /// <summary>
        /// Gets or sets if the control allows negative numbers
        /// </summary>
        [Category("Appearance")]
        [DefaultValue(false)]
        [Localizable(true)]
        [Description("Indicates if the control allows negative numbers")]
        public bool AllowNegatives
        {
            get
            {
                if (ViewState["an"] == null)
                {
                    ViewState.Add("an", false);
                }
                return Boolean.Parse(ViewState["an"].ToString());
            }
            set
            {
                ViewState["an"] = value;
            }
        }

        /// <summary>
        /// Returns a string with the number in a format that can be parsed
        /// </summary>
        [Category("Appearance")]
        [DefaultValue("0")]
        [Localizable(true)]
        [Description("Returns a string with the number in a format that can be parsed")]
        public string Value
        {
            get
            {
                numberValue = CleanFormat();
                if (!String.IsNullOrEmpty(numberValue))
                {                    
                    return numberValue;
                }
                else
                {
                    return "0";
                }                
            }            
        }

        /// <summary>
        /// Returns true if a value has not been input
        /// </summary>
        public bool IsNull
        {
            get
            {
                return String.IsNullOrEmpty(CleanFormat());
            }
        }

        internal string CssForjQuery
        {
            get
            {
                return String.Format("{0}{1}", NumberTextBox.suffixCss, NumericType.ToString());
            }
        }

        /// <summary>
        /// Text align within the input
        /// </summary>
        [Category("Appearance")]
        [DefaultValue("HorizontalAlign.Right")]
        [Localizable(true)]
        [Description("Text align within the input")]
        public HorizontalAlign HorizontalAlign
        {
            get
            {
                return hoAl;
            }
            set
            {
                hoAl = value;
            }
        }
        #endregion

        /// <summary>
        /// Check if there is a jQueryScriptManager control in the page
        /// </summary>
        /// <param name="e">Event argument</param>        
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (!Page.IsPostBack)
            {
                if (!DesignMode)
                    CheckQueryManager();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
           
            if (!CssClass.Contains(CssForjQuery))
            {
                base.CssClass = String.Format("{0} {1}",CssForjQuery, CssClass);
                if (AllowNegatives)
                {
                    base.CssClass = String.Format("{0}{1}", base.CssClass, allowNegatives);
                }
            }
            if (Attributes.CssStyle["text-align"] == null)
            {
                Attributes.CssStyle.Add("text-align", HorizontalAlign.ToString().ToLower());
            }
            else
            {
                Attributes.CssStyle["text-align"] = HorizontalAlign.ToString().ToLower();
            }            
        }

        /// <summary>
        /// Remove the non-numeric characters from Text property value
        /// </summary>
        /// <returns>Return the numeric value</returns>
        private string CleanFormat()
        {            
            string aux = Text;
            aux = aux.Replace('%', ' ');
            aux = aux.Replace(jQueryManager.CoinSymbol, "");
            aux = aux.Replace(jQueryManager.ThousandSeparator.ToString(), "");
            if (NumericType == NumericFormat.Integer)
            {
                int auxInt = 0;
                if (!int.TryParse(aux, out auxInt))
                {
                    aux = "0";
                }                
            }
            else
            {
                double auxDbl = 0;
                if (!double.TryParse(aux, out auxDbl))
                {
                    aux = "0";
                }   
            }
            return aux.Trim();
        }

        private void CheckQueryManager()
        {
            Common.Instance.CheckJQueryScriptManager(Page);
        }        
    }
}
